package exchange;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Arrays;
import java.util.HashMap;
import java.util.concurrent.BlockingQueue;

public class NewConnectionHandler implements Runnable {

	BlockingQueue<Socket> socketQueue;
	String[] clientsAllowed;
	private HashMap<String, ExchangeClient> clientsMap;
	private HashMap<String, ExchangeEngine> enginesMap;

	public NewConnectionHandler(BlockingQueue<Socket> socketQueue,
			String[] clientsAllowed, HashMap<String, ExchangeClient> clientMap, HashMap<String,ExchangeEngine> enginesMap) {
		this.socketQueue = socketQueue;
		this.clientsAllowed = clientsAllowed;
		this.clientsMap = clientMap;
		this.enginesMap = enginesMap;
		}

	@Override
	public void run() {

		ObjectInputStream in = null;
		ObjectOutputStream out = null;

		Socket connection;
		try {
			while (true) {
				connection = socketQueue.take(); // thread is waiting here until
													// new
													// element appearers.
				Parser parser = new Parser();
				String reason = null;
				boolean isGoodMessage = true;
				System.out.println("CONNECTION TAKEN");
				in = new ObjectInputStream(connection.getInputStream());
				out = new ObjectOutputStream(connection.getOutputStream());
				String message = (String) in.readObject();
				System.out.println("IN : "+message);

				String type = parser.takeValue(message, "35");

				if (isGoodMessage && !"A".equals(type)) {
					reason = "Wrong type message(35); expect A";
					isGoodMessage = false;
				}
				String clientId = parser.takeValue(message, "39");

				if (isGoodMessage
						&& !Arrays.asList(clientsAllowed).contains(clientId)) {
					reason = "Wrong senderId(39); you are not authorised to trade";
					isGoodMessage = false;
				}

				if (isGoodMessage && clientsMap.containsKey(clientId)) {
					reason = "client with the same ID is already registered";
					isGoodMessage = false;
				}

				if (isGoodMessage) {
					ExchangeClient client = new ExchangeClient(in, out,
							clientId,enginesMap,clientsMap);
					clientsMap.put(clientId, client); // register client
					out.writeObject("35=A");
					out.flush();
					System.out.println("CLIENT REGISTERED");
					new Thread(client).start(); // START NEW CLIENT
				} else {
					out.writeObject("35=5|58=" + reason);
					out.flush();
					System.out.println("OUT: "+reason);
					System.out.println ("Authorisation failed, close connection");
					connection.close();
					in.close();
					out.close();
				}
			}

		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

	}

}
